package com.zsd.android.glidelib.pool;

import android.graphics.Bitmap;
import android.os.Build;
import android.util.LruCache;

import java.util.TreeMap;

public class BitmapPoolImpl extends LruCache<Integer, Bitmap> implements BitmapPool {

    //为了筛选出合适的Bitmap容器
    private TreeMap<Integer, String> treeMap;

    /**
     * @param maxSize for caches that do not override {@link #sizeOf}, this is
     *                the maximum number of entries in the cache. For all other caches,
     *                this is the maximum sum of the sizes of the entries in this cache.
     */
    public BitmapPoolImpl(int maxSize) {
        super(maxSize);
        treeMap = new TreeMap<>();
    }

    @Override
    public void put(Bitmap bitmap) {
        //存入复用池
        // todo 条件一：bitmap.isMutable() == true;
        if (!bitmap.isMutable()) {
            //bitmap
            return;
        }
        // todo 条件二：bitmap的size必须要小于复用池的maxSize
        int bitmapSize = getBitmapSize(bitmap);
        if (bitmapSize >= maxSize()) {
            return;
        }
        //bitmap存入LruCache
        put(bitmapSize, bitmap);
        //存入筛选的容器
        treeMap.put(bitmapSize, null);
    }

    private int getBitmapSize(Bitmap bitmap) {
        int result = 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            result = bitmap.getAllocationByteCount();
        } else {
            result = bitmap.getByteCount();
        }
        return result;
    }

    /**
     * 用于获取bitmap
     * @param width
     * @param height
     * @param config
     * @return
     */
    @Override
    public Bitmap get(int width, int height, Bitmap.Config config) {
        /**
         * ALPHA_8 理论上 实际上Android会自动做处理 只有透明度 8代表8位，1个字节
         * 大小：w*h*1
         *
         * RGB_565 理论上 实际上Android会自动做处理 R红色（5位），G绿色（6位），B蓝色（5位） 总共16位，2个字节，没有透明度
         * 大小：w*h*2
         *
         * ARGB_4444 理论上 实际上Android会自动做处理 A透明度（4位），R红色（4位），G绿色（4位），B蓝色（4位） 总共16位 2个字节，
         * 大小：w*h*2
         *
         * 质量最高：
         * ARGB_8888 理论上 实际上Android会自动做处理 A透明度（8位），R红色（8位），G绿色（8位），B蓝色（8位） 总共32位  4个字节，
         * 大小：w*h*4
         *
         * 常用：RGB_565和ARGB_8888
         */
        int size = width * height * (config == Bitmap.Config.ARGB_8888 ? 4 : 2);
        //可以查找到容器里面和size一样大的，也可以比size还要大的Key
        Integer key = treeMap.ceilingKey(size);
        //如果treeMap还没有put，那么一定是null
        if (key == null) {
            //没有找到合适的可复用的key
            return null;
        }
        //查找容器取出来的key必须小于计算出来的size
        //因为这样子概率比较小，所以要增减概率，所以判断条件为 (size * 2)
        if (key <= (size * 2)) {
            //复用池如果要取出来，必须要移除掉，不给其他地方使用
            Bitmap bitmap = remove(key);
            return bitmap;
        }
        return null;
    }

    //每一个元素大小
    @Override
    protected int sizeOf(Integer key, Bitmap value) {
        return getBitmapSize(value);
    }

    //元素被移除
    @Override
    protected void entryRemoved(boolean evicted, Integer key, Bitmap oldValue, Bitmap newValue) {
        super.entryRemoved(evicted, key, oldValue, newValue);
    }
}
